#include "stlmainwindow.h"
#include "ui_stlmainwindow.h"

STLMainWindow::STLMainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::STLMainWindow)
{
    ui->setupUi(this);
    iniUI();
    m_sp_stl_reader = std::make_shared<STLReader>();
}

STLMainWindow::~STLMainWindow()
{
    delete ui;
}

void STLMainWindow::iniUI()
{
    fLabCurFile = new QLabel;
    fLabCurFile->setMinimumWidth(150);
    fLabCurFile->setText("当前文件：");
    ui->statusbar->addWidget(fLabCurFile);
}

void STLMainWindow::initModelWidget()
{
    if(m_sp_modelWidget)
        m_sp_modelWidget->deleteLater();

    m_sp_modelWidget = std::make_shared<STLModelWidget>(m_sp_stl_reader, this);

    setCentralWidget(m_sp_modelWidget.get());

    m_sp_modelWidget->show();
}

void STLMainWindow::updateCurrentFileLabel(const QString &stl_file_path)
{
    QFileInfo fileInfo(stl_file_path);
    QString fileName = fileInfo.fileName();

    // 更新文件名显示
    fLabCurFile->setText(QString("当前文件: %1").arg(fileName));
    fLabCurFile->setToolTip(stl_file_path);

    // 更新文件大小显示
    qint64 size = fileInfo.size();
    QString sizeText;
    // if (size < 1024) {
    //     sizeText = QString("%1 字节").arg(size);
    // } else if (size < 1024 * 1024) {
    //     sizeText = QString("%1 KB").arg(size / 1024);
    // } else {
    //     sizeText = QString("%1 MB").arg(size / (1024 * 1024), 1, 'f', 2);
    // }

    // 更新窗口标题
    setWindowTitle(QString("%1 - STL Viewer").arg(fileName));
}

void STLMainWindow::createSlicingWindow(SliceInfo slice_info)
{
    // 创建切片窗口（设置父对象为模型控件）
    m_sp_sliceWidget = std::make_shared<SliceMainWindow>(m_sp_modelWidget.get());

    // 初始化切片控件
    m_sp_sliceWidget->initSliceWidget(m_sp_stl_reader, slice_info);

    // 设置窗口属性
    m_sp_sliceWidget->setWindowTitle("切片视图");
    m_sp_sliceWidget->setWindowFlags(Qt::Window);
    m_sp_sliceWidget->resize(this->width(), this->height());

    // 显示窗口
    m_sp_sliceWidget->show();
}

void STLMainWindow::handleSlicingSettings(const QVector3D& planeNormal, float cameraDistance, float slicingStride)
{
    // 创建切片信息结构
    SliceInfo sliceInfo;
    sliceInfo.plane_norm = m_sp_modelWidget->transformNormalToModelSpace(planeNormal);
    sliceInfo.distance = cameraDistance;
    sliceInfo.thickness = slicingStride;

    // 创建切片窗口
    createSlicingWindow(sliceInfo);
}

/************槽函数定义**************/
void STLMainWindow::on_actionOpenSTL_triggered()
{
    // 获取用户选择的文件路径
    QString filePath = QFileDialog::getOpenFileName(this, tr("打开STL文件"), QDir::homePath(), tr("STL文件 (*.stl *.STL);;所有文件 (*.*)"));

    if (filePath.isEmpty())
        return;  // 用户取消了选择

    try {
        // 尝试读取STL文件
        bool success = m_sp_stl_reader->readMeshesFromSTLFile(filePath, STL_READ_TYPE::BINARY);
        if (!success)
        {
            QMessageBox::warning(this, tr("错误"), tr("无法读取STL文件"));
            return;
        }

        // 文件读取成功，初始化模型显示控件
        initModelWidget();

        // 修改状态栏文本
        updateCurrentFileLabel(filePath);

    } catch (const std::exception &e) {
        QMessageBox::critical(this, tr("错误"),
                              tr("读取STL文件时发生错误: %1").arg(e.what()));
    }
}

void STLMainWindow::on_actionSliceModel_triggered()
{
    QVector3D camera_pos = m_sp_modelWidget->getCurrentCameraPos();
    QVector3D plane_norm = camera_pos.normalized();
    float camera_dis = camera_pos.length();
    float stride = 0.1f;

    SliceInfo slice_info = {plane_norm, camera_dis, stride};

    createSlicingWindow(slice_info);
}

void STLMainWindow::on_actionSetupSliceInfo_triggered()
{
    m_sp_slicingSettingDialog = std::make_shared<SlicingSettingsDialog>(m_sp_modelWidget.get());
    m_sp_slicingSettingDialog->setWindowTitle("设置切片信息");
    m_sp_slicingSettingDialog->setWindowFlags(Qt::Window);
    m_sp_slicingSettingDialog->resize(this->width() / 2, this->height() / 2);
    connect(m_sp_slicingSettingDialog.get(), &SlicingSettingsDialog::slicingSettingsConfirmed,
            this, &STLMainWindow::handleSlicingSettings);
    m_sp_slicingSettingDialog->show();
}

void STLMainWindow::on_actionSaveAs_triggered()
{
    // 获取用户选择的保存路径
    QString filePath = QFileDialog::getSaveFileName(
        this,
        tr("保存截图"),
        QDir::homePath() + "/untitled.png",  // 默认路径和文件名
        tr("PNG图像 (*.png);;所有文件 (*.*)")
        );

    // 如果用户取消了选择
    if (filePath.isEmpty()) {
        return;
    }

    // 确保文件后缀是.png
    if (!filePath.endsWith(".png", Qt::CaseInsensitive)) {
        filePath += ".png";
    }

    // 调用保存函数
    if (m_sp_modelWidget) {
        bool success = m_sp_modelWidget->saveFramebufferToPNG(filePath);

        if (success) {
            QMessageBox::information(this, tr("保存成功"), tr("截图已保存到: %1").arg(filePath));
        } else {
            QMessageBox::warning(this, tr("保存失败"), tr("无法保存截图到指定路径"));
        }
    }
}


void STLMainWindow::on_pushButton_clicked()
{
    // 获取用户选择的文件路径
    QString filePath = QFileDialog::getOpenFileName(this, tr("打开STL文件"), QDir::homePath(), tr("STL文件 (*.stl *.STL);;所有文件 (*.*)"));

    if (filePath.isEmpty())
        return;  // 用户取消了选择

    try {
        // 尝试读取STL文件
        bool success = m_sp_stl_reader->readMeshesFromSTLFile(filePath, STL_READ_TYPE::BINARY);
        if (!success)
        {
            QMessageBox::warning(this, tr("错误"), tr("无法读取STL文件"));
            return;
        }

        // 文件读取成功，初始化模型显示控件
        initModelWidget();

        // 修改状态栏文本
        updateCurrentFileLabel(filePath);

    } catch (const std::exception &e) {
        QMessageBox::critical(this, tr("错误"),
                              tr("读取STL文件时发生错误: %1").arg(e.what()));
    }
}

